package dao

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"qrsj-collect/backend/models"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

var (
	DB *gorm.DB
)

func InitMysql() error {
	var err error
	databaseHost := os.Getenv("DATABASE_HOST")
	databasePort := os.Getenv("DATABASE_PORT")
	databaseUser := os.Getenv("DATABASE_USER")
	databasePassword := os.Getenv("DATABASE_PASSWORD")
	databaseName := os.Getenv("DATABASE_NAME")
	if databaseHost == "" || databasePort == "" || databaseUser == "" || databasePassword == "" || databaseName == "" {
		return fmt.Errorf("database environment variables are not set properly")
	}
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", databaseUser, databasePassword, databaseHost, databasePort, databaseName)
	sqlDB, err := sql.Open("mysql", dsn)
	if err != nil {
		return fmt.Errorf("failed to open SQL connection: %w", err)
	}
	// 设置最大连接数
	sqlDB.SetMaxOpenConns(100)
	sqlDB.SetMaxIdleConns(20)
	sqlDB.SetConnMaxLifetime(time.Hour)

	DB, err = gorm.Open(mysql.New(mysql.Config{
		Conn: sqlDB,
	}), &gorm.Config{
		Logger: logger.New(
			log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
			logger.Config{
				SlowThreshold:             time.Second,   // Slow SQL threshold
				LogLevel:                  logger.Silent, // Log level
				IgnoreRecordNotFoundError: true,          // Ignore ErrRecordNotFound error for logger
				ParameterizedQueries:      true,          // Don't include params in the SQL log
				Colorful:                  false,         // Disable color
			},
		),
	})
	if err != nil {
		return fmt.Errorf("mysql init failed: %w", err)
	}
	err = DB.AutoMigrate(&models.User{}, &models.LoginRecord{}, &models.App{}, &models.Menu{}, &models.AddressCategory{}, &models.Coord{})
	// DB.Exec("ALTER TABLE login_records ADD CONSTRAINT fk_users_login_record FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE;")
	if err != nil {
		return fmt.Errorf("mysql auto migrate failed: %w", err)
	}
	return nil
}

func CloseMysql() {
	sqlDB, err := DB.DB()
	if err != nil {
		log.Printf("mysql close failed: %v", err)
	}
	sqlDB.Close()
}

func Ping() error {
	sqlDB, err := DB.DB()
	if err != nil {
		return fmt.Errorf("mysql ping failed: %w", err)
	}
	return sqlDB.Ping()
}

func Stats() sql.DBStats {
	sqlDB, _ := DB.DB()
	return sqlDB.Stats()
}

func CheckDBConnection() error {
	if err := Ping(); err != nil {
		log.Printf("Database connection error: %v", err)
		return fmt.Errorf("服务端连接失败，请稍后再试")
	}
	return nil
}
